/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Collections;

namespace ELE.EnterpriseLibrary.Naming.Spi
{
	/// <summary>
  /// This interface represents a factory for obtaining the state of an object for binding. 
  /// <br/><br/>The ONDI framework allows for object implementations to be loaded in dynamically via object factories. 
  /// For example, when looking up a printer bound in the name space, if the print service binds printer names to 
  /// References, the printer Reference could be used to create a printer object, so that the caller of lookup can 
  /// directly operate on the printer object after the lookup. 
  /// <br/><br/>An IObjectFactory is responsible for creating objects of a specific type. In the above example, you 
  /// may have a PrinterObjectFactory for creating Printer objects. 
  /// <br/><br/>For the reverse process, when an object is bound into the namespace, ONDI provides state factories. 
  /// Continuing with the printer example, suppose the printer object is updated and rebound: 
  /// <br/><br/>ctx.Rebind("inky", printer);
  /// <br/><br/>The service provider for ctx uses a state factory to obtain the state of printer for binding into its 
  /// namespace. A state factory for the Printer type object might return a more compact object for storage in the 
  /// naming system. 
  /// <br/>A state factory must implement the StateFactory interface. In addition, the factory class must be public 
  /// and must have a public constructor that accepts no parameters. 
  /// <br/><br/>The GetStateToBind() method of a state factory may be invoked multiple times, possibly using different
  ///  parameters. The implementation is thread-safe. 
  /// <br/><br/>IStateFactory is intended for use with service providers that implement only the INamingContext interface. 
  /// IDirStateFactory is intended for use with service providers that implement the INamingDirContext interface. 
	/// </summary>
	public interface IStateFactory
	{
    /// <summary>
    /// Retrieves the state of an object for binding. 
    /// <br/><br/>NamingManager.GetStateToBind() successively loads in state factories and invokes this method on them 
    /// until one produces a non-null answer. DirectoryManager.getStateToBind() successively loads in state factories. 
    /// If a factory implements DirStateFactory, then DirectoryManager invokes DirStateFactory.getStateToBind(); 
    /// otherwise it invokes StateFactory.getStateToBind(). 
    /// <br/><br/>When an exception is thrown by a factory, the exception is passed on to the caller of 
    /// NamingManager.GetStateToBind() and DirectoryManager.GetStateToBind(). The search for other factories that may 
    /// produce a non-null answer is halted. A factory should only throw an exception if it is sure that it is the only 
    /// intended factory and that no other factories should be tried. If this factory cannot create an object using the 
    /// arguments supplied, it should return null. 
    /// <br/><br/>The name and nameCtx parameters may optionally be used to specify the name of the object being created. 
    /// See the description of "Name and Context Parameters" in IObjectFactory.GetObjectInstance() for details. 
    /// If a factory uses nameCtx it should synchronize its use against concurrent access, since context implementations 
    /// are not guaranteed to be thread-safe. 
    /// <br/><br/>The name and environment parameters are owned by the caller. The implementation will not modify these 
    /// objects or keep references to them, although it may keep references to clones or copies.
    /// </summary>
    /// <param name="obj">A non-null object whose state is to be retrieved</param>
    /// <param name="name">The name of this object relative to nameCtx, or null if no name is specified.</param>
    /// <param name="nameCtx">The context relative to which the name parameter is specified, or null if name is relative to 
    /// the default initial context.</param>
    /// <param name="environment">The possibly null environment to be used in the creation of the object's state.</param>
    /// <returns>The object's state for binding; null if the factory is not returning any changes</returns>
    object GetStateToBind(object obj, IName name, INamingContext nameCtx, Hashtable environment);
    
	}
}
